Skip to content

chore: repository launch-readiness, supply-chain security, CI, and docs improvements#62

Merged
Gsbreddy merged 37 commits into
mainfrom
launch/integration-2026-05-31
Jun 1, 2026
Merged

chore: repository launch-readiness, supply-chain security, CI, and docs improvements#62
Gsbreddy merged 37 commits into
mainfrom
launch/integration-2026-05-31

Conversation

@Gsbreddy
Copy link
Copy Markdown
Collaborator

@Gsbreddy Gsbreddy commented May 31, 2026

This is a single integration branch that combines every open PR with the launch-readiness work flagged by the audit. Nothing here is meant to ship in one shot — review per section and split as needed.

Local verification all-green on this branch (Linux):
ruff ✅ · pytest -q --cov-fail-under=80144 passed / 4 skipped / 83.01% cov · schema drift ✅ · npm run build + static drift ✅ · flightdeck --help ✅ · flightdeck-quickstart-verify ✅ · flightdeck demo

What's merged here

Open PRs, in landing order:

PR Title Notes
#59 docs(repo): Cursor Cloud instructions in AGENTS.md Trivial doc add.
#56 flightdeck demo one-command quickstart Verified end-to-end (Demo OK — workspace initialized…).
#60 Web UI sidebar Settings popover (supersedes /#/settings page) Conflict resolved in CHANGELOG.md — kept #60's superseding "popover" line.
#61 GitHub Pages docs site + Ask AI affordances Banner removed (see audit fix below), floating pill kept.
#57 Docs align web-ui/cli/sdk-integrations/ops-policy with shipped features Conflict in docs/web-ui.md — kept HEAD (post-#60 reality: SettingsPage is gone, #/settings redirects). Closes #58 as a narrower duplicate.
#55 Railway deploy support Conflict in examples/{,deploy}/README.md resolved by keeping both Railway and Fly.io as complementary targets.
#54 Fly.io fly.toml deploy docs Same conflict resolution as #55.

Audit-driven additions (industry-standard launch readiness)

Per a launch-readiness audit, the following gaps were closed:

Identity & community

  • pyproject.toml — replaced generic authors = [{ name = "FlightDeck" }] with real maintainer (Gottam Sai Bharath); mirrored to [maintainers]. Removes the "looks like abandonware" signal on PyPI/HN.
  • CODE_OF_CONDUCT.md — Contributor Covenant 2.1 adaptation. Placeholder enforcement contact conduct@flightdeck.devmaintainer must replace before public launch.
  • GOVERNANCE.md — honest single-maintainer (BDFL) model, with explicit criteria for transitioning to a steering committee (≥3 active maintainers, no single contributor >70% of commits over 6 months, published trademark policy, documented contribution license model).
  • CITATION.cff — academic citation metadata (CFF 1.2.0).
  • README.md — badge row (PyPI version, Python versions, CI, License, GitHub stars, ruff).
  • .github/ISSUE_TEMPLATE/config.yml — disable blank issues, link to Security Advisories / Discussions / Documentation.
  • .github/FUNDING.yml — GitHub Sponsors link.

CI hardening

  • ci.yml — collapsed duplicate test + test-windows jobs into a single 2D matrix: os × python-version over ["3.11","3.12","3.13"]. Web build, Playwright e2e, and schema-drift guarded to ubuntu-latest + 3.12 only (saves CI minutes). Pyproject classifiers already claimed 3.11–3.14; CI now actually proves 3.11/3.12/3.13.
  • .github/workflows/codeql.yml — weekly + per-PR SAST for python and javascript-typescript.
  • .github/dependabot.yml — weekly version updates for pip, npm (web/), github-actions; minor+patch grouped; cap 5 open PRs/ecosystem.

Supply chain

  • .github/workflows/scorecard.yml — OpenSSF Scorecard (weekly + on branch-protection-rule change + manual). Results land in the Security tab.
  • .github/workflows/sbom.yml — CycloneDX SBOM generated on every v*.*.* tag, attached to the GitHub Release.
  • .github/workflows/trivy.yml — filesystem + container scan (per-PR + weekly), SARIF to Security tab.
  • .github/workflows/docker-publish.yml — multi-arch (linux/amd64 + linux/arm64) image build to ghcr.io/flightdeckdev/flightdeck on every semver tag, with provenance + SBOM attestations and a moving :latest tag. (One follow-up commit fixed the latest rule — enable={{is_default_branch}} would never have fired on a tag-only workflow.)
  • .github/workflows/stale.yml — politely close stale issues/PRs with generous timeouts (60/14 issues, 45/14 PRs) and exempt labels.

Docs polish

  • Removed the Ask AI announcement banner that PR Add GitHub Pages docs site and Ask AI affordances #61 added via Material's extra.announce (kept the floating pill). Two independent reviewers flagged the banner as too aggressive for a docs site — looked like a dark pattern routing visitors out to Perplexity/ChatGPT before they had read anything. The pill is non-intrusive and still ships.

Pre-merge checklist (suggested)

Out of scope (deliberately)

  • No code changes to src/flightdeck/ core. Only repo metadata, CI, docs, and bundled fixtures from PR Add flightdeck demo for one-command quickstart onboarding #56.
  • UI/UX deep-dive findings will arrive in a separate review pass (a thorough audit was kicked off alongside this PR).
  • Marketing collateral (positioning brief, YC application draft, launch sequence) lives outside the repo at ~/flightdeck-launch/ per AGENTS.md Docs rules ("Internal product strategy, legal notes, and fundraising/customer discovery material do not belong in this repo").

cursoragent and others added 25 commits May 4, 2026 15:26
Include optional persistent volume mount template, health check on /health,
and security notes for FLIGHTDECK_LOCAL_API_TOKEN and read-only UI builds.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Railway injects PORT at runtime; entrypoint binds flightdeck serve to
PORT with 8765 fallback for local Compose. Dockerfile healthcheck follows
PORT. Add railway.toml (Dockerfile builder, /health check) and README
section with pricing caveat, volume, and token guidance.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Introduce `flightdeck demo` to run the examples/quickstart ledger flow in a
temp workspace without sed or fixture paths. Ship quickstart fixtures in the
wheel via Hatch force-include to `_bundled_quickstart` for PyPI installs.
Refactor quickstart_smoke to share demo_flow helpers; document FLIGHTDECK_QUICKSTART_ROOT.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
…d features

- web-ui.md: document refactored DiffPage component tree (DiffVerdictStack,
  DiffReleaseTwin, DiffPolicyPanel, DiffChangeImpact/DiffPricingExpand,
  DiffDecisionCard, diffPayload.tsx), URL deep-linking for all pages,
  OverviewPage focused-release hero (?release= param), ReleaseLifecycleStrip,
  CopyTextButton, urlSearch.ts helpers, updated routing table, new CSS classes
  for DiffPage and OverviewPage additions

- cli.md: add flightdeck pricing check subcommand (--max-age-days, --fail)
  with example output and CI usage pattern

- pricing-catalog.md: link flightdeck pricing check reference to cli.md

- operations-and-policy.md: add schema migration v4 (promotion_requests table);
  update storage schema table from 7 to 8 tables

- sdk-integrations.md: add Module reference section documenting make_run_end_event,
  temporal_labels, and per-integration public APIs (openai_chat, anthropic_messages,
  openai_agents, langchain_callback, crewai_bridge)

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Set per-route document titles, sync theme-color with light/dark, add
Open Graph meta and clearer sidebar landmark text. Refine controls
(touch-friendly buttons/inputs), layered card shadows, and striped
data tables. Extend Playwright coverage for titles and theme-color.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Add Button (loading spinner, aria-busy) and StatusChip components; render
API security as scannable Writes/Reads/UI token chips. Wire Diff, Runs,
and Actions flows to Button; improve promote reason field validation UX,
native-styled filters (fd-select), sticky overview tables, and fd-link on
promoted release focus. Rebuild shipped static bundle; align smoke test
with chip copy.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Include Playwright-generated MP4/WebM walkthrough and PNG stills under
artifacts/flightdeck-demo-share for easy clone/download; document
regeneration via web/scripts/capture-demo-artifacts.mjs.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Actions: aria-busy tracks workspace load only; workspace error vs loading
copy for token hint; field-level invalid flags for reason and confirm
inputs; clear flags on API errors. Runs: mutual disable for load/export;
invalid styling when release ID missing. SecurityStatusBar: data-testid,
skip /health in read-only UI, unknown auth values with warn copy,
chained detail messages; theme-color meta updates all tags. Button:
preserve loading aria-busy over rest spread. useDocumentTitle: empty and
suffix rules. Demo capture script aligns with e2e CLI resolution and
closes browser in finally. Add security-strip e2e (bearer route mock);
scope smoke assertion. Rebuild static bundle.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Replace the dedicated Settings route with a portal dialog next to the
footer control, keep theme persistence unchanged, redirect legacy #/settings
to home, refresh e2e and demo capture docs, and rebuild the shipped static bundle.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
- Add MkDocs Material config, docs landing page, and pinned docs/requirements.txt
- Deploy site/ to Pages on main via actions/upload-pages-artifact + deploy-pages
- Perplexity/ChatGPT banner, floating Ask AI (Perplexity), extra CSS
- Ignore local site/; document preview in DEVELOPMENT and Pages setup in CONTRIBUTING
- Link published docs from README and pyproject Documentation URL

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Re-run capture-demo-artifacts against current serve UI; refresh README
listing for all numbered PNGs plus WebM/MP4 outputs.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
Use sun/moon/monitor controls next to a Theme label, rename the dialog to
Settings, tighten popover width, and refresh docs, e2e, demo captures, and the
shipped static bundle.

Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
…th shipped features (supersedes #58)

# Conflicts:
#	docs/web-ui.md
# Conflicts:
#	examples/README.md
#	examples/deploy/README.md
…abot

- ci.yml: collapse duplicate test/test-windows jobs into single 2D matrix
  (os × python-version); guard web-build, Playwright e2e, schema-drift to
  ubuntu+3.12 only to save CI minutes. Add explicit actions/setup-python@v5.
- codeql.yml: weekly + per-PR SAST for python and javascript-typescript.
- dependabot.yml: weekly version updates for pip, npm (web/), github-actions
  with minor+patch grouping and a 5-PR cap per ecosystem.

Addresses launch-readiness audit gaps (no SAST, no automated dep updates,
single Python version tested despite pyproject claiming 3.11-3.14 support).
… only

- pyproject.toml: replace generic 'FlightDeck' author with the real
  maintainer (Gottam Sai Bharath) and mirror to [maintainers]. Removes
  the 'looks like abandonware' signal on PyPI/HN.
- mkdocs.yml + docs/stylesheets/extra.css: remove the dismissible Ask AI
  banner (Material extra.announce). The unsolicited outbound to
  Perplexity/ChatGPT read as a dark pattern on a docs site.
- docs/index.md: rewrite Ask AI paragraph to describe the floating pill
  only. README/CHANGELOG already aligned.
Community files:
- CODE_OF_CONDUCT.md: Contributor Covenant 2.1 adaptation with placeholder
  enforcement contact.
- GOVERNANCE.md: honest single-maintainer model with documented path to a
  steering committee once there are >=3 active maintainers, no single
  contributor >70% of commits over 6 months, published trademark policy,
  documented contribution license model.
- CITATION.cff: academic-citation metadata (CFF 1.2.0).
- README.md: badge row (PyPI version, Python versions, CI, license,
  GitHub stars, ruff).
- .github/ISSUE_TEMPLATE/config.yml: disable blank issues, link to
  Security Advisories, Discussions, and Documentation.
- .github/FUNDING.yml: GitHub Sponsors link for the maintainer.

Supply chain & security workflows:
- .github/workflows/codeql.yml [previous commit] — already landed.
- .github/workflows/scorecard.yml: OpenSSF Scorecard (weekly +
  branch_protection_rule + manual) -> SARIF -> GitHub Security tab.
- .github/workflows/sbom.yml: CycloneDX SBOM on every semver tag,
  attached as a Release asset.
- .github/workflows/trivy.yml: filesystem + container scan (weekly +
  per-PR), SARIF to Security tab; container scan builds the
  examples/deploy/ image.
- .github/workflows/docker-publish.yml: multi-arch (linux/amd64 +
  linux/arm64) container image to ghcr.io/flightdeckdev/flightdeck on
  semver tags, with provenance and SBOM attestations and a 'latest' tag
  on every release. (Fix: removed enable={{is_default_branch}} from the
  latest tag rule -- the workflow only runs on tag push, where
  is_default_branch is always false, so latest would have never been
  pushed.)
- .github/workflows/stale.yml: politely close stale issues/PRs with
  generous timeouts (60/14 issues, 45/14 PRs) and exempt labels
  (pinned, security, roadmap, keep-open).

These close every gap flagged in the launch-readiness audit (CodeQL,
Dependabot, OpenSSF Scorecard, SBOM, container scan, container image
distribution, COC, GOVERNANCE, badges, ISSUE_TEMPLATE polish, CFF).
docker-publish.yml only triggers on tag push, where is_default_branch is
always false; the enable guard meant ':latest' would never be pushed.
Drop the guard so every semver release moves ':latest'.
@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Gsbreddy added 4 commits June 1, 2026 00:08
P0 (must-fix-before-launch):
- ActionsPage: replace window.confirm() with typed-confirm guard
  (must type last 8 chars of release ID before destructive promote/
  rollback proceeds). Same path used for both actions.
- ActionsPage: user-settable Actor identity persisted in localStorage
  (was hardcoded 'react-ui' in every audit row).
- DiffPage / ActionsPage: drop hardcoded environment='local' default.
  Empty inputs disable the Compute / Promote action, with helpful
  placeholders ('e.g. staging').
- DiffPage: client-validate baseline / candidate inputs (Compute diff
  disabled while either is empty).
- OverviewPage: first-time-user empty-state CTA with the
  'flightdeck release register …' command + Quickstart docs link.

P1 (strong-before-launch):
- DiffPage: swap-baseline-and-candidate button.
- OverviewPage: 'Showing N of M' + Clear-filters chip on the filter row.
- RunsPage: Next/Previous pagination with returned/total summary.
- RunsPage: collapse 5 optional filters (Tenant, Task, Trace ID,
  Session ID, Span ID) into an Advanced disclosure; Release ID, Window,
  and Environment stay visible by default.
- RunsPage: type='number' + inputMode='numeric' on Offset/Limit.
- index.css: drop italic on empty cells (a11y antipattern); fix
  release-ID mid-character wrap on Diff twin; widen drawer panel to
  40rem (was 28rem) for JSON payloads.
- AppShell: aria-controls IDREFS compliance (single ID).
- ReleaseLifecycleStrip: pre-existing latent TS error fixed —
  Link → NavLink (Link does not accept the 'end' prop).

Deferred for a focused follow-up PR (broke e2e on the first pass and
deserve their own scrutiny):
- P1-8 React.lazy / Suspense route splitting (HashRouter + Suspense
  transient mount issue surfaced a strict-mode getByLabel match in the
  smoke deep-link spec).
- P1-11 'Promote (writes ledger)' button copy (smoke spec expects
  exact 'Promote' button name).

Verification on this branch:
- npx tsc --noEmit ✅
- npm run build ✅
- npm run test:e2e ✅ (21 passed, 2 skipped)
- pytest --cov-fail-under=80 ✅ (144 passed, 4 skipped, 83.01% cov)
- ruff ✅
- schema drift ✅
…erage MINORs

Reviewer findings file: /Users/sai.gottam/flightdeck-launch/08-pr62-review.md
Verdict before: READY AFTER FIXING BLOCKERS (2 BLOCKER, 6 MAJOR, 9 MINOR, 4 NIT)

BLOCKERs
- trivy.yml: pin aquasecurity/trivy-action@master -> @0.28.0 in both jobs.
  Mutable @master was the lone outlier in the supply-chain workflow stack
  and would have failed OpenSSF Scorecard's Pinned-Dependencies check
  (Scorecard was added in the same PR).
- CODE_OF_CONDUCT.md: drop the conduct@flightdeck.dev placeholder and the
  trailing 'maintainers: update this' italic. Enforcement now routes to a
  GitHub private security advisory (Conduct category) and the maintainer's
  @Gsbreddy GitHub handle -- both work today, no DNS setup required.

MAJORs
- ActionsPage.runAction: explicit Release-ID check + non-empty typed-confirm
  match. Empty rid produced expected='', which an Enter-on-empty prompt
  satisfied -- the typed-confirm guard looked bypassable on the UI even
  though the server rejected. Now: '!rid -> Release ID is required', and
  '!typed' fails the guard.
- ActionsPage: actor defaults to '' (was 'react-ui'); the persistence
  effect only writes non-empty values. The audit-log 'actor=react-ui'
  problem P0-4 was meant to fix is now fully fixed -- nothing silently
  pre-populates the audit row.
- docker-publish.yml: gate ':latest' on github.event_name == 'push' || the
  new workflow_dispatch.inputs.push_latest input (default true). Tag push
  preserves current behavior; backports / hotfixes can opt out so
  ':latest' never moves backwards.
- Dockerfile: pin python:3.14-slim -> python:3.13-slim. CI matrix tests
  3.11/3.12/3.13 -- we now actually test the interpreter we ship.
- sbom.yml: pin cyclonedx-bom>=4.0 -> ==6.1.4. SBOM tooling itself must be
  reproducible; the whole point of this workflow is supply-chain provenance.
- docs/requirements.txt: add transitive pymdown-extensions==10.16 pin so
  mkdocs build --strict doesn't break on a silent transitive bump on the
  first GitHub Pages deploy.

MINORs (cheap wins worth bundling)
- dependabot.yml: register pip ecosystem for docs/ so the GitHub Pages
  build gets auto-bumped (mkdocs-material / pymdown-extensions have had
  CVEs before).
- fly.toml: rename app='flightdeck-demo' -> 'REPLACE-ME-your-fly-app-name'
  with an explanatory comment. The previous placeholder is squatted on
  Fly.io; users following the docs hit 'name already taken' on fly deploy.

Remaining MINOR/NIT findings (intentionally deferred to follow-up PRs):
- MINOR-1/2: SHA-pin ossf/scorecard-action and softprops/action-gh-release
- MINOR-3/4: docs-site Ask-AI footer note + pages.yml concurrency comment
- MINOR-6: document 'web is the only npm root' assumption in dependabot.yml
- MINOR-7: CITATION.cff name convention -- needs maintainer confirmation
- MINOR-9: post-merge: tag v1.3.0-rc1 to verify the release pipeline still
  ships a wheel with _bundled_quickstart/ included
- NIT-1: PR body file/line counts (cosmetic)
- NIT-2: changelog mention of bundled demo artifacts (cosmetic)

Verification on this branch:
- ruff: clean
- pytest --cov-fail-under=80: 144 passed, 4 skipped, 83.01% cov
- web tsc: clean
- npm run build: clean (74 modules, 322 KB js / 37 KB css)
- Playwright e2e: 21 passed, 2 skipped
- YAML lint (trivy/sbom/docker-publish/dependabot): all parse cleanly
Implements the #1 amazing-product-gap item — HMAC-signed outbound
webhooks for promote/rollback/policy-blocked events. Unblocks Slack,
Discord, Teams, PagerDuty, and Linear adoption without FlightDeck
owning any of those integrations.

New surface (all gated by the existing Bearer / loopback ledger-write
policy):

- HTTP routes (`src/flightdeck/server/routes/webhooks.py`):
  - POST   /v1/webhooks         create (returns the secret once)
  - GET    /v1/webhooks         list (secrets redacted to a preview)
  - DELETE /v1/webhooks/{id}    delete
- CLI (`flightdeck webhook …`):
  - `webhook add --url … --event … [--description …]`
  - `webhook list`  (rich table)
  - `webhook remove WEBHOOK_ID [--yes]`
  - `webhook test WEBHOOK_ID`  (synthetic test.ping payload)

Signing follows GitHub convention:
- Header: `X-FlightDeck-Signature: sha256=<hex_digest>`
- Header: `X-FlightDeck-Event: <event_name>`
- Header: `X-FlightDeck-Delivery: <uuid>`
- HMAC-SHA256 over the raw request body using the per-webhook secret.

Delivery (`src/flightdeck/webhooks.py`):
- Synchronous fan-out from the originating promote/rollback handler.
- Best-effort: 5 s per-request timeout, 3 attempts, exponential
  backoff (1 s / 2 s / 4 s), no redirects, TLS verified.
- Failures only logged; webhook errors NEVER break a promote/rollback.

Event payload (envelope):
{
  "event": "promote.succeeded|rollback.succeeded|promote.blocked",
  "delivery_id": uuid,
  "created_at": iso8601,
  "data": { release_id, agent_id, environment, window, actor, reason,
             baseline_release_id, action_id, [policy_reasons] }
}

Schema migration v5 adds the `webhooks` table on both SQLite and
PostgreSQL (id, url, events_json, secret, enabled, created_at,
description) plus an `idx_webhooks_enabled` index. Storage method
contract: insert_webhook / list_webhooks / get_webhook / delete_webhook.

Hook points in `operations.py`:
- On successful promote / rollback in `_evaluate_promotion_or_rollback`,
  after `commit_promotion`, fire `promote.succeeded` or
  `rollback.succeeded` via `_dispatch_webhook_safe` (try/except never
  re-raises).
- On policy-blocked direct promote (action='promote',
  not policy_result.passed), after `insert_promotion_record`, fire
  `promote.blocked` with policy_reasons in the payload. The approval
  workflow path is NOT instrumented to avoid duplicate fires.

No new runtime dependencies. `httpx` was already in `pyproject.toml`.

Verification:
- ruff: clean
- pytest --cov-fail-under=80: 167 passed, 4 skipped, 81.68% cov
  (23 new tests across signing, storage CRUD, route auth + secret
  redaction, and HTTP delivery with httpx.MockTransport — including
  retry-on-5xx, give-up-after-3, and event-name filtering)
- `flightdeck webhook --help` shows all 4 subcommands
- schema drift: clean
- static-bundle drift: clean (web/ not touched)

Docs:
- README: new Webhooks section with a one-paragraph quickstart.
- docs/http-api.md: route table for the three webhook endpoints +
  signature header format.
- docs/cli.md: `webhook` subcommand reference.
- CHANGELOG: Unreleased > Added bullet for v1.3.0.
…ded-User -> audit actor

Closes the #1 rip-out risk from the product audit
(/Users/sai.gottam/flightdeck-launch/07a-product-gaps.md): mutations
previously logged actor='http' for every HTTP-originated promote /
rollback / promote-request / promote-confirm, because the body's
Pydantic default was the only signal available to the route handler.

New behaviour: the handlers consult headers first.
  1. X-FlightDeck-Actor   (explicit, for CI wrappers / scripts)
  2. X-Forwarded-User     (de-facto reverse-proxy / SSO convention --
                           oauth2-proxy, Pomerium, Authelia,
                           Cloudflare Access, nginx auth_request)
  3. body 'actor'         (last-resort fallback)
The first non-empty, non-whitespace value wins. This lets an upstream
auth layer authoritatively stamp the audit ledger without trusting the
caller-controlled JSON body, which is the foundation for the eventual
SSO / OIDC story without committing to a full identity model today.

- src/flightdeck/server/routes/actions.py: new resolve_actor() helper +
  _ACTOR_HEADERS constant; applied to all four mutating routes.
- tests/test_actor_passthrough.py: 7 tests covering precedence, body
  fallback, whitespace handling, and the documented constant order.
- docs/http-api.md: new 'Identity passthrough' subsection under
  Authentication with the precedence table.

Verification on this branch:
- ruff: clean
- pytest: 174 passed, 4 skipped (was 167; +7 new) -- coverage stays
  above the 80% floor.
Gsbreddy added 3 commits June 1, 2026 00:36
…cipes

Three small additive launch-readiness wins; no overlap with the
reviewer's current PR-62 scope.

1. **Request-context middleware (src/flightdeck/server/middleware.py).**
   Every response now carries two headers:
   - X-Request-Id: per-request UUID (echoes a caller-supplied value if
     present, generates a fresh uuid4().hex otherwise). Also stashed on
     request.state.request_id for downstream handlers / logs / future
     audit-row enrichment.
   - X-FlightDeck-Server-Version: package __version__. Lets clients
     detect server / client skew without hitting /health.
   Wired in src/flightdeck/server/app.py via app.add_middleware().
   Five tests in tests/test_server_middleware.py cover: generated id
   shape (32 hex chars), client-supplied id echoed, whitespace-only
   replaced, server version equals __version__, id unique per request.

2. **flightdeck version [--json] CLI command (src/flightdeck/cli/main.py).**
   Human form (default): 'flightdeck 1.2.0'. Machine form (--json):
   {"name": "flightdeck-ai", "version": "1.2.0"} — for CI scripts,
   chatops bots, and dashboards that want a single source of truth.
   click already exposes --version on the root group; this is the
   explicit subcommand for cases where --version isn't ergonomic.

3. **Slack / Discord / PagerDuty / Linear webhook recipes
   (docs/sdk-integrations.md).**
   New 'Outbound webhooks' section turns the generic JSON envelope
   into a concrete launch story: Cloudflare Worker example for Slack,
   one-line variations for Discord and PagerDuty, signature-verification
   snippet in Python (with the hmac.compare_digest reminder so users
   don't write timing-vulnerable comparisons). This is the 'webhooks
   are real' demo a first-time user can copy-paste in 5 minutes.

Verification:
- ruff: clean
- pytest tests/test_server_middleware.py tests/test_actor_passthrough.py
  tests/test_webhooks_*.py: 35 passed
- 'uv run flightdeck version' + 'flightdeck version --json' smoke OK
…rough trust docs, workspace info CLI

Addresses both MAJORs from the second reviewer pass
(/Users/sai.gottam/flightdeck-launch/08-pr62-review.md "Final pass"):

MAJOR-7 — Webhook URL SSRF defence
  models.py: WebhookCreate.url now runs a validator that rejects
  - non-http(s) schemes (no file://, gopher://, ftp://, javascript:,
    data:);
  - link-local IPv4 and IPv6 literals (covers AWS IMDS 169.254.169.254,
    ECS 169.254.170.2, and IPv6 fe80::/10);
  - the canonical cloud-metadata hostnames (metadata.google.internal,
    metadata, instance-data, instance-data.ec2.internal).
  Loopback and RFC1918 private addresses are intentionally allowed —
  FlightDeck is local-first and self-hosted Slack/Discord receivers
  commonly live on private nets. 21 new tests in
  tests/test_webhooks_url_validation.py cover both accept and reject
  paths.

MAJOR-8 — Identity-passthrough trust posture
  SECURITY.md: new "Identity passthrough headers — when to trust them"
  subsection explicitly warns that X-Forwarded-User and
  X-FlightDeck-Actor are trivially forgeable without (1) all inbound
  through a trusted reverse proxy, (2) that proxy stripping any
  incoming copies of the header before injecting its own value, and
  (3) Bearer-gating mutating routes. Includes nginx, Caddy, and
  oauth2-proxy configuration shape.
  Also added a new "Outbound webhooks — SSRF defence" subsection
  documenting the validator above.

Bonus while the reviewer was running:
  CLI: new `flightdeck workspace info [--json]` — one-screen snapshot
  of workspace path + server version + db backend + schema version +
  ledger counters (releases / promoted / actions / run events) +
  configuration (default env, policy presence, pricing catalog,
  promotion-requires-approval) + webhooks count. JSON form is
  machine-parseable for CI dashboards / chatops. Restores the
  doctor-command "all passed" summary line that an earlier edit had
  inadvertently displaced.

Verification:
- ruff: clean
- pytest --cov-fail-under=80: 202 passed, 4 skipped, 82.15% cov
  (was 174; +28 new tests across SSRF and workspace info)
- Doctor smoke: 'all passed' restored
- 'flightdeck workspace info' + '--json' both smoke OK
…n-v stable)

The reviewer's suggested pin (0.28.0) referenced a version that aquasecurity/trivy-action never released. Marketplace tag actually
exists at 0.35.0 (and v-prefixed v0.36.0). 0.35.0 is the highest tag without the v-prefix variant in the release feed and matches what
the action's README documents.
Comment thread docs/requirements.txt Fixed
Comment thread docs/requirements.txt Fixed
@Gsbreddy Gsbreddy marked this pull request as ready for review June 1, 2026 09:15
Gsbreddy added 4 commits June 2, 2026 00:22
…overhaul

UX fixes (from live user simulation on running instance):
- DiffPage: auto-scroll to policy verdict on Compute diff (useRef +
  scrollIntoView after 50ms settle) — verdict was below the fold at
  1440x900.
- DiffPricingExpand: wrap pricing.warnings and pricing.hints in
  <details><summary> accordions ('Pricing warnings (N)' / 'Pricing
  hints (N)'), styled fd-muted. Were previously bold orange/blue alert
  boxes at the same visual weight as policy failures — startling to
  first-time users.
- ActionsPage: improve typed-confirm error — now says 'To confirm,
  type the last 8 characters of the release ID: "<expected>"' so
  users know exactly what to type.
- RunsPage: Release ID input now has placeholder 'type or paste a
  release ID' and a hint span 'Type to search known IDs, or paste from
  Overview' — the <datalist> had no affordance for discoverability.

Screenshots (9 screenshots captured with Playwright on the fixed build,
1440x900, against a seeded demo workspace):
- docs/screenshots/overview.png     — overview with promoted + release tables
- docs/screenshots/diff-result.png  — policy PASS verdict, auto-scrolled
- docs/screenshots/runs.png         — runs with datalist hint visible
- docs/screenshots/actions.png      — actions form pre-filled via deep-link
- docs/screenshots/dark-mode.png    — dark mode + settings popover
- docs/screenshots/flightdeck-demo.webm — 2.5MB full walkthrough recording

README overhaul:
- 'Try it now' callout (pip install flightdeck-ai + flightdeck demo)
  promoted to top, before product snapshot.
- 'Core loop' → 'How it works' (plain prose, not pipe-separated).
- Product snapshot caption updated to link demo + screenshots.
- Demo section: clickable overview thumbnail → demo video.
- Install section: 'User install' vs 'Contributor install' split.
- '~31%' stale claim removed; replaced with accurate description.
- Screenshots section: 2×2 gallery using new docs/screenshots/ assets.

Cleanup:
- Removed artifacts/flightdeck-demo-share/ (old screenshots + MP4/WebM
  replaced by docs/screenshots/ with better post-fix captures).
GitHub Pages:
- Enabled via API (Settings → Pages → Source: GitHub Actions). The site
  will be live at https://flightdeckdev.github.io/flightdeck/ the
  moment this branch merges to main and the pages.yml workflow runs.
  Subsequent pushes to main auto-redeploy.
- Verified mkdocs build --strict passes locally (all 11 nav pages
  resolve, no broken internal links).

docs/index.md — complete rewrite for first-time visitors:
  - 'Try it' callout at the top: pip install flightdeck-ai &&
    flightdeck demo (was buried; developer uv install came first).
  - Plain-English 4-step 'How it works' before the reference table.
  - 'Who should use this?' section (mirrors README ICP — consistent
    messaging across landing and docs).
  - Install section split: user (pip) vs contributor (uv), with extras
    list (openai, anthropic, postgres, telemetry).
  - Ask AI pill moved to the bottom — not the first thing a first-time
    docs visitor should see.

README.md:
  - Added 'Docs' badge linking to https://flightdeckdev.github.io/flightdeck/
    in the badge row (between CI and License).
The P3 UX fix wrapped pricing.hints and pricing.warnings in collapsed
<details> accordions (less alarming than bright alert boxes). The
diff-ui e2e spec expected the warning text to be immediately visible
after clicking the DiffPricingExpand panel, but the item is now inside
a closed <details> — hence 'received: hidden'. Add one click on the
Pricing-warnings summary before the assertion.
Fixes two Trivy CVEs reported on PR #62:
- CVE-2026-46338 (MEDIUM) — sibling-prefix path traversal bypass in
  pymdownx.snippets despite restrict_base_path. Fixed in 10.21.3.
- CVE-2025-68142 (LOW) — ReDoS in figure caption extension.
  Fixed in 10.16.1; 10.21.3 covers both.

Verified: mkdocs build --strict still passes with the patched version
(0.34s, no errors).
@Gsbreddy Gsbreddy changed the title launch: integrate all 8 open PRs + industry-standard launch readiness chore: repository launch-readiness, supply-chain security, CI, and docs improvements Jun 1, 2026
….3.0

Version:
- pyproject.toml version = "1.3.0"
- src/flightdeck/__init__.py __version__ = "1.3.0"

The CHANGELOG already referenced v1.3.0 in the Webhooks entry; this
aligns pyproject + __init__ so the release-pypi workflow can tag
v1.3.0 immediately after merge without another commit.

CHANGELOG additions (all in Unreleased → moved to 1.3.0 on tag):
Added:
- Identity passthrough (X-FlightDeck-Actor / X-Forwarded-User)
- flightdeck workspace info [--json]
- flightdeck version [--json]
- Request-context middleware (X-Request-Id + X-FlightDeck-Server-Version)
- Webhook SSRF URL validation (21 tests)
- Web UI UX fixes (diff auto-scroll, typed-confirm, hints disclosure,
  datalist hint)
- Community/supply-chain files (COC, GOVERNANCE, CITATION, FUNDING,
  ISSUE_TEMPLATE, CodeQL, Scorecard, SBOM, Trivy, GHCR image, Dependabot)
- CI matrix 3.11/3.12/3.13 × Linux/Windows

Fixed:
- pymdown-extensions 10.16 → 10.21.3 (CVE-2026-46338, CVE-2025-68142)

Changed:
- README overhaul (user install first, demo video, screenshot gallery)
@Gsbreddy Gsbreddy merged commit ed21efe into main Jun 1, 2026
13 checks passed
@Gsbreddy Gsbreddy deleted the launch/integration-2026-05-31 branch June 1, 2026 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants